package com.xiaoq;

import com.mongodb.*;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.Morphia;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author xinpeng created on 16/7/21-上午11:27.
 */

@Configuration
@EnableConfigurationProperties(MongoProperties.class)
public class MongoConfig {

    private static Logger logger = LoggerFactory.getLogger(MongoConfig.class);

    @Resource
    private MongoProperties mongoProperties;


//    ConnectTimeout=30000;ConnectionLifetime=300000;MinimumPoolSize=8;MaximumPoolSize=256;Pooled=true




    @Bean
    public MongoClient mongoClient() throws UnknownHostException {

        List<ServerAddress> serverAddresses = new ArrayList<>();
        for (String replicaSet : mongoProperties.getReplicaSets()){
            String[] parts = StringUtils.split(replicaSet, ":");
            Assert.state(parts.length==2, "replicaSet shoule be defined as 'host:port', not '" + Arrays.toString(parts) + "'");
            ServerAddress serverAddress = new ServerAddress(parts[0],Integer.parseInt(parts[1]));
            serverAddresses.add(serverAddress);
        }

        List<MongoCredential> credentialsList = new ArrayList<>();
        MongoCredential credentia = MongoCredential.createCredential(
                mongoProperties.getUsername(), mongoProperties.getDatabase(), mongoProperties.getPassword().toCharArray());
        credentialsList.add(credentia);

        return new MongoClient(serverAddresses,credentialsList,getConfOptions());
//        return  new MongoClient(serverAddresses,getConfOptions());
    }


    private MongoClientOptions getConfOptions() {

        return new MongoClientOptions.Builder()
                .socketKeepAlive(true) // 是否保持长链接
                .connectTimeout(30000) // 链接超时时间
                .socketTimeout(5000) // read数据超时时间
                .readPreference(ReadPreference.secondaryPreferred()) // 最近优先策略
                .maxConnectionLifeTime(300000)
                .connectionsPerHost(50) // 每个地址最大请求数
                .maxWaitTime(1000 * 60 * 2) // 长链接的最大等待时间
                .threadsAllowedToBlockForConnectionMultiplier(50) // 一个socket最大的等待请求数
                .writeConcern(WriteConcern.NORMAL).build();
    }

    @Bean
    public Datastore datastore() throws Exception {
        logger.info("Morhpia Datastore....init().....................");
        Morphia morphia = new Morphia();

        //告诉Morphia在哪里找到你的类
        //可以为不同的包或者类进行多次的调用
        morphia.mapPackage("com.xiaoq.entity");
        //创建datastore，并连接到指定数据库
        //datastore有两个参数，第一个用来连接到MongoDB，第二个是数据库的名字。
        long start = System.currentTimeMillis();


        Datastore datastore = morphia.createDatastore(mongoClient(), mongoProperties.getDatabase());
        datastore.ensureIndexes();

        long end = System.currentTimeMillis();

        long time = end - start;

        logger.debug("time = "+time);
        return datastore;
    }

    @Bean
    public MongoTemplate mongoTemplate() throws Exception {
        logger.info("MongoTemplate....init().....................");
        MongoTemplate template = null;
        try {
            template = new MongoTemplate(mongoClient(),mongoProperties.getDatabase());
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        return template;
    }
}
